1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package com.sun.media.sound;
26
27
28
29
30
31
32
33
34 public class SoftSincResampler extends SoftAbstractResampler {
35
36 float[][][] sinc_table;
37 int sinc_scale_size = 100;
38 int sinc_table_fsize = 800;
39 int sinc_table_size = 30;
40 int sinc_table_center = sinc_table_size / 2;
41
42 public SoftSincResampler() {
43 super();
44 sinc_table = new float[sinc_scale_size][sinc_table_fsize][];
45 for (int s = 0; s < sinc_scale_size; s++) {
46 float scale = (float) (1.0 / (1.0 + Math.pow(s, 1.1) / 10.0));
47 for (int i = 0; i < sinc_table_fsize; i++) {
48 sinc_table[s][i] = sincTable(sinc_table_size,
49 -i / ((float)sinc_table_fsize), scale);
50 }
51 }
52 }
53
54
55 public static double sinc(double x) {
56 return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
57 }
58
59
60 public static float[] wHanning(int size, float offset) {
61 float[] window_table = new float[size];
62 for (int k = 0; k < size; k++) {
63 window_table[k] = (float)(-0.5
64 * Math.cos(2.0 * Math.PI * (double)(k + offset)
65 / (double) size) + 0.5);
66 }
67 return window_table;
68 }
69
70
71 public static float[] sincTable(int size, float offset, float scale) {
72 int center = size / 2;
73 float[] w = wHanning(size, offset);
74 for (int k = 0; k < size; k++)
75 w[k] *= sinc((-center + k + offset) * scale) * scale;
76 return w;
77 }
78
79 public int getPadding()
80 {
81 return sinc_table_size / 2 + 2;
82 }
83
84 public void interpolate(float[] in, float[] in_offset, float in_end,
85 float[] startpitch, float pitchstep, float[] out, int[] out_offset,
86 int out_end) {
87 float pitch = startpitch[0];
88 float ix = in_offset[0];
89 int ox = out_offset[0];
90 float ix_end = in_end;
91 int ox_end = out_end;
92 int max_p = sinc_scale_size - 1;
93 if (pitchstep == 0) {
94
95 int p = (int) ((pitch - 1) * 10.0f);
96 if (p < 0)
97 p = 0;
98 else if (p > max_p)
99 p = max_p;
100 float[][] sinc_table_f = this.sinc_table[p];
101 while (ix < ix_end && ox < ox_end) {
102 int iix = (int) ix;
103 float[] sinc_table =
104 sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
105 int xx = iix - sinc_table_center;
106 float y = 0;
107 for (int i = 0; i < sinc_table_size; i++, xx++)
108 y += in[xx] * sinc_table[i];
109 out[ox++] = y;
110 ix += pitch;
111 }
112 } else {
113 while (ix < ix_end && ox < ox_end) {
114 int iix = (int) ix;
115 int p = (int) ((pitch - 1) * 10.0f);
116 if (p < 0)
117 p = 0;
118 else if (p > max_p)
119 p = max_p;
120 float[][] sinc_table_f = this.sinc_table[p];
121
122 float[] sinc_table =
123 sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
124 int xx = iix - sinc_table_center;
125 float y = 0;
126 for (int i = 0; i < sinc_table_size; i++, xx++)
127 y += in[xx] * sinc_table[i];
128 out[ox++] = y;
129
130 ix += pitch;
131 pitch += pitchstep;
132 }
133 }
134 in_offset[0] = ix;
135 out_offset[0] = ox;
136 startpitch[0] = pitch;
137
138 }
139 }